//
//  Evaluator.swift
//  PrattParser
//
//  Created by 神经骚栋 on 2023/9/16.
//

import Cocoa

class Evaluator: NSObject {
    
    public static func eval(_ node: Node?) -> MObj? {
        if let nodeValue = node as? IntegerExpression {
            return MInt(nodeValue.value)
        } else if let nodeValue = node as? PrefixExpression {
            if (nodeValue.operatorValue == "-") {
                return minus(node);
            } else if (nodeValue.operatorValue == "+") {
                return eval(nodeValue.right);
            }
        } else if let nodeValue = node as? InfixExpression {
            let left = eval(nodeValue.left);
            let right = eval(nodeValue.right);
            return op(left, right, nodeValue.operatorValue);
        }
        return nil;
    }
    public static func op(_ left: MObj?, _ right: MObj?, _ operatorValue: String?) -> MObj? {
        if let leftValue = left as? MInt,
           let rightValue = right as? MInt {
            switch(operatorValue) {
            case "+" :
                return MInt(leftValue.number + rightValue.number)
            case "-" :
                return MInt(leftValue.number - rightValue.number)
            case "*" :
                return MInt(leftValue.number * rightValue.number)
            case "/" :
                return MInt(leftValue.number / rightValue.number)
            case "^" :
                return MInt(pow(leftValue.number, rightValue.number))
            default:
                return nil;
            }
        }
        return nil;
    }
        
    public static func minus(_ node: Node?) -> MObj? {
        if let nodeValue = node as? PrefixExpression {
            let m : MObj? = eval(nodeValue.right);
            if let mValue = m as? MInt {
                if (nodeValue.operatorValue == "-") {
                    mValue.number = -mValue.number
                }
                return mValue;
            }
        }
        return nil;
    }
}
